#pragma once
#include "Socket.hpp"
#include <memory>
#include "Commn.hpp"
#include <strings.h>
#include <functional>
#include <sys/wait.h>

namespace TcpserverModule
{
    using namespace SocketModule;
    using TcpHandler_t = std::function<void(SockPtr sock, InetAddr client)>;
    class TcpServer
    {
    public:
        TcpServer(int port)
            : _port(port),
              _sock(std::make_unique<Tcpsocket>()),
              _isrunning(false)
        {
            // 创建tcp服务
            _sock->BuildTcpserver(_port);
        }
        void RegisterHandler(TcpHandler_t Handler)
        {
            _handler = Handler;
        }
        void Loop()
        {
            _isrunning = true;
            while (_isrunning)
            {
                sockaddr_in client_addr;
                bzero(&client_addr, sizeof(client_addr));
                // accept
                SockPtr ret = _sock->accpetor(&client_addr);
                InetAddr client(client_addr);
                // 开始处理任务
                //在accpet之后再fork。
                pid_t fd = fork();
                if (fd == 0)
                {
                    // LOG(LogLevel::INFO) << "子进程关闭的文件描述符: " << ret->FD();
                    _sock->Close(); // 子进程关闭listen
                    if (fork() > 0)
                        exit(0);
                    // 孙子进程
                    _handler(ret, client); //为什么要把这个交给上层来调用呢? 如果就在这里调用会怎样? 
                    //我们Tcp只负责通信，真正的信息处理交给上层 
                    exit(0);
                }
                // LOG(LogLevel::INFO) << "父进程关闭的文件描述符: " << ret->FD();
                ret->Close(); // 父进程关闭accpet
                pid_t wid = waitpid(fd, nullptr, 0);
                (void)wid;
            }
            _isrunning = false;
        }
        ~TcpServer() {}

    private:
        int _port;
        std::unique_ptr<Socket> _sock;
        bool _isrunning;
        TcpHandler_t _handler;
    };
}
